package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.ReportDao;
import com.itheima.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 统计报表服务
 */
@Service(interfaceClass = ReportService.class)
@Transactional
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private OrderDao orderDao;

    /**
     * 获得运营统计数据
     * Map数据格式：
     * todayNewMember ‐> number
     * totalMember ‐> number
     * thisWeekNewMember ‐> number
     * thisMonthNewMember ‐> number
     * todayOrderNumber ‐> number
     * todayVisitsNumber ‐> number
     * thisWeekOrderNumber ‐> number
     * thisWeekVisitsNumber ‐> number
     * thisMonthOrderNumber ‐> number
     * thisMonthVisitsNumber ‐> number
     * hotSetmeal ‐> List<Setmeal>
     */
    public Map<String, Object> getBusinessReport() throws Exception {

        //获得当前日期
        String today = DateUtils.parseDate2String(DateUtils.getToday());
        //获得本周一的日期
        String thisWeekMonday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());
        //获得本月第一天的日期
        String firstDay4ThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());

        //今日新增会员数
        Integer todayNewMember = memberDao.findMemberCountByDate(today);
        //总会员数
        Integer totalMember = memberDao.findMemberTotalCount();
        //本周新增会员数
        Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday);
        //本月新增会员数
        Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth);

        //今日预约数
        Integer todayOrderNumber = orderDao.findOrderCountByDate(today);
        //本周预约数
        Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday);
        //本月预约数
        Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDay4ThisMonth);

        //今日到诊数
        Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);
        //本周到诊数
        Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday);
        //本月到诊数
        Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDay4ThisMonth);

        //热门套餐（取前4）  TOP榜  top10  top3  top4   limit 10
        List<Map> hotSetmeal = orderDao.findHotSetmeal();

        Map<String, Object> result = new HashMap<>();
        result.put("reportDate", today);
        result.put("todayNewMember", todayNewMember);
        result.put("totalMember", totalMember);
        result.put("thisWeekNewMember", thisWeekNewMember);
        result.put("thisMonthNewMember", thisMonthNewMember);
        result.put("todayOrderNumber", todayOrderNumber);
        result.put("thisWeekOrderNumber", thisWeekOrderNumber);
        result.put("thisMonthOrderNumber", thisMonthOrderNumber);
        result.put("todayVisitsNumber", todayVisitsNumber);
        result.put("thisWeekVisitsNumber", thisWeekVisitsNumber);
        result.put("thisMonthVisitsNumber", thisMonthVisitsNumber);
        result.put("hotSetmeal", hotSetmeal);
        return result;
    }

    @Autowired
    private ReportDao reportDao;

    public Map<String, Object> getIncomeReport(String begin, String end) {
        Map<String, Object> map = new HashMap<>();   //封装整个数据
        //map[id:...,  name: ....,  value:.....,count:.....]
        List<Map<String, Object>> lists = reportDao.getIncomeReport(begin, end);

        List<String> setMealList = new ArrayList<>();   //封装套餐名
        List<Map<String, Object>> income = new ArrayList<>();   //封装各种套餐收入
        int sum = 0;

        if (lists != null && lists.size() > 0) {

            for (Map<String, Object> map1 : lists) {

                String name = (String) map1.get("name");
                setMealList.add(name);

                Float value = (Float) map1.get("value");
                long count = (long) map1.get("count");
                //求每种套餐收入
                Map<String, Object> map2 = new HashMap<>();
                map2.put("name", name);
                map2.put("value", value * count);
                sum += value * count;
                income.add(map2);   //income":[A:....,B:....,C:...,]
            }
            setMealList.add("总收入");

            Map<String, Object> mp3 = new HashMap<>();
            mp3.put("name", "总收入");
            mp3.put("value", sum);
            income.add(mp3);

            map.put("setMeals", setMealList);
            map.put("income", income);

            return map;
        } else {
            throw new RuntimeException("暂无数据");
        }

    }



    /*"data":{
        "group":["baby","child","teenager","youth"],
        "count":[3,4,8,10]
    },*/

    public HashMap<String, Object> getAgeReport() {

        int cBaby = 0;      //0-6岁
        int cChild = 0;  //7-12岁
        int cTeen = 0;   //13-17岁
        int cYoung = 0;     //18-45岁
        int cMiddle = 0;    //46-69岁
        int cOld = 0;       //>69
        int others = 0;//其他
        int age = 0;

        HashMap<String, Object> map = new HashMap<>();  //封装数据

        //map:[id:....   count:...... birthday:......]
        List<Map<String, Object>> list = reportDao.getAgeReport();

        if (list != null && list.size() > 0) {

            for (Map<String, Object> map1 : list) {
                long count = (long) map1.get("count");
                Date date = (Date) map1.get("birthday");
                if (date == null) {
                    others++;
                    continue;
                }
                //年龄计算

                Calendar now = Calendar.getInstance();
                now.setTime(new Date());// 当前时间
                Calendar birth = Calendar.getInstance();
                birth.setTime(date);
                if (birth.after(now)) {
                    throw new IllegalArgumentException("输入的生日不合法");
                } else {
                    int yearNow = now.get(Calendar.YEAR);  //当前年份
                    int monthNow = now.get(Calendar.MONTH);  //当前月份
                    int dayOfMonthNow = now.get(Calendar.DAY_OF_MONTH); //当前日期

                    int yearBirth = birth.get(Calendar.YEAR);
                    int monthBirth = birth.get(Calendar.MONTH);
                    int dayOfMonthBirth = birth.get(Calendar.DAY_OF_MONTH);
                    age = yearNow - yearBirth;   //计算整岁数
                    if (monthNow <= monthBirth) {
                        if (monthNow == monthBirth) {
                            if (dayOfMonthNow < dayOfMonthBirth)
                                age--;//当前日期在生日之前，年龄减一
                        } else {
                            age--;//当前月份在生日之前，年龄减一

                        }
                    }

                    if (age >= 0 && age <= 6) {
                        cBaby += count;
                    } else if (age >= 7 && age <= 12) {
                        cChild += count;
                    } else if (age >= 13 && age <= 17) {
                        cTeen += count;
                    } else if (age >= 18 && age <= 45) {
                        cYoung += count;
                    } else if (age >= 46 && age <= 69) {
                        cMiddle += count;
                    } else if (age >= 70 && age <= 120) {
                        cOld += count;
                    }
                }
            }
        } else {
            throw new RuntimeException("暂无数据");
        }

        List<Integer> countList = new ArrayList<>();

        List<String> Names = new ArrayList<>();

        if (cBaby > 0) {
            Names.add("婴幼儿");
            countList.add(cBaby);
        }
        if (cTeen > 0) {
            Names.add("少儿");
            countList.add(cTeen);
        }
        if (cTeen > 0) {
            Names.add("青少年");
            countList.add(cTeen);
        }
        if (cYoung > 0) {
            Names.add("青年");
            countList.add(cYoung);
        }
        if (cMiddle > 0) {
            Names.add("中年");
            countList.add(cMiddle);
        }
        if (cOld > 0) {
            Names.add("老年");
            countList.add(cOld);
        }
        if (others > 0) {
            Names.add("其他");
            countList.add(others);
        }
        map.put("Names", Names);
        map.put("countList", countList);
        return map;
    }
}